/*
 * @Author: SongXiao
 * @Date: 2023-04-24 16:58:39
 * @LastEditors: SongXiao
 * @LastEditTime: 2023-04-25 14:58:39
 * @Description: file content
 */
import React, { useEffect, useRef } from 'react';
import Map from 'ol/Map';
import Stamen from 'ol/source/Stamen.js';
import View from 'ol/View.js';
import { Layer, Tile as TileLayer } from 'ol/layer.js';
import { fromLonLat, toLonLat, transform } from 'ol/proj.js';
import Feature from 'ol/Feature';
import { getCenter, getWidth } from 'ol/extent.js';
import { Point, LinearRing, Circle, LineString, Polygon } from "ol/geom";
import * as d3 from 'd3'
import * as topojson from 'topojson'
import us from './us.json';

class CanvasLayer extends Layer {
    constructor(options) {
        super(options);

        this.features = options.features;


        let areaList = [[119.66197103106072, 30.406979958560083], [119.76496785723259, 30.427579323794458], [119.86659139238884, 30.430325905825708], [119.95036214434197, 30.426206032778833], [120.17695516192009, 30.411099831606958], [120.23463338457634, 30.283383767153833], [120.24012654863884, 30.222958962466333], [120.19206136309197, 30.173520485903833], [120.13575643145134, 30.118588845278833], [119.93388265215447, 30.148801247622583], [119.80342000567009, 30.198239724185083], [119.71003621660759, 30.284757058169458], [119.65785115801384, 30.349301735903833], [119.66197103106072, 30.406979958560083]]

        console.log("this.features")
        console.log(this.features)

        this.svg = d3
            .select(document.createElement('div'))
            .append('svg')
            .style('position', 'absolute');

        this.svg.append('path').datum(this.features).attr('class', 'boundary');
    }

    getSourceState() {
        return 'ready';
    }

    render(frameState) {
        // console.log("frameState")
        // console.log(frameState)
        const width = frameState.size[0];
        const height = frameState.size[1];
        const projection = frameState.viewState.projection;
        const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
        let d3Path = d3.geoPath().projection(d3Projection);

        const pixelBounds = d3Path.bounds(this.features);
        const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
        const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];

        const geoBounds = d3.geoBounds(this.features);
        const geoBoundsLeftBottom = fromLonLat(geoBounds[0], projection);
        const geoBoundsRightTop = fromLonLat(geoBounds[1], projection);
        let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
        if (geoBoundsWidth < 0) {
            geoBoundsWidth += getWidth(projection.getExtent());
        }
        const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];

        const widthResolution = geoBoundsWidth / pixelBoundsWidth;
        const heightResolution = geoBoundsHeight / pixelBoundsHeight;
        const r = Math.max(widthResolution, heightResolution);
        const scale = r / frameState.viewState.resolution;

        const center = toLonLat(getCenter(frameState.extent), projection);
        const angle = (-frameState.viewState.rotation * 180) / Math.PI;

        d3Projection
            .scale(scale)
            .center(center)
            .translate([width / 2, height / 2])
            .angle(angle);

        d3Path = d3Path.projection(d3Projection);
        d3Path(this.features);

        this.svg.attr('width', width);
        this.svg.attr('height', height);

        this.svg.select('path').attr('d', d3Path);

        return this.svg.node();
    }
}

const MapShow = function () {
    const map = useRef(null)
    useEffect(() => {
        if (map.current) return
        map.current = new Map({
            layers: [
                new TileLayer({
                    source: new Stamen({
                        layer: 'watercolor',
                    }),
                }),
            ],
            target: 'main-map',
            view: new View({
                center: fromLonLat([-97, 38]),
                zoom: 4,
            }),
        });

        console.log("us")
        console.log(us)
        /**
         * Load the topojson data and create an ol/layer/Image for that data.
         */
        const layer = new CanvasLayer({
            features: topojson.feature(us, us.objects.counties),
        });

        map.current.addLayer(layer);

        // 点击出现详情弹窗
        map.current && map.current.on('singleclick', (e) => {
            console.log(e.coordinate)
            var transformedCoordinate = transform(e.coordinate, 'EPSG:3857', 'EPSG:4326');
            console.log(transformedCoordinate)
        })
    }, [])

    return (
        <div className="map-show">
            <div id="main-map" />
        </div>
    )
}

export default MapShow